package token

import "fmt"

type TokenType string

type Token struct {
	Type    TokenType
	Literal string
}

func (t Token) String() string {
	return fmt.Sprintf("Token(%s,%s)", t.Type, t.Literal)
}

func (t TokenType) String() string {
	return string(t)
}

const (
	ILLEGAL = "ILLEGAL"
	EOF     = "EOF"

	// Identifiers + literals
	IDENT = "IDENT" // add, foobar, x, y, ...
	INT   = "INT"   // 1343456

	// Operators
	ASSIGN   = "="
	PLUS     = "+"
	MINUS    = "-"
	BANG     = "!"
	ASTERISK = "*"
	SLASH    = "/"

	LT     = "<"
	GT     = ">"
	EQ     = "=="
	NOT_EQ = "!="

	// Delimiters
	COMMA     = ","
	SEMICOLON = ";"

	LPAREN = "("
	RPAREN = ")"

	LBRACE = "{"
	RBRACE = "}"

	// Keywords
	FUNCTION    = "FUNCTION"
	LET         = "LET"
	TRUE        = "TRUE"
	FALSE       = "FALSE"
	IF          = "IF"
	ELSE        = "ELSE"
	RETURN      = "RETURN"
	END         = "END"
	WHILE       = "WHILE"
	FOR         = "FOR"
	TO          = "TO"
	IN          = "IN"
	BREAK       = "BREAK"
	CONTINUE    = "CONTINUE"
	PRINT       = "PRINT"
	IMPORT      = "IMPORT"
	EXPORT      = "EXPORT"
	PACKAGE     = "PACKAGE"
	INTERFACE   = "INTERFACE"
	STRUCT      = "STRUCT"
	CLASS       = "CLASS"
	METHOD      = "METHOD"
	CONSTRUCTOR = "CONSTRUCTOR"
	NEW         = "NEW"
	NULL        = "NULL"
	THIS        = "THIS"
	SUPER       = "SUPER"
	EXTENDS     = "EXTENDS"
)

var keywords = map[string]TokenType{
	"fn":       FUNCTION,
	"let":      LET,
	"true":     TRUE,
	"false":    FALSE,
	"if":       IF,
	"else":     ELSE,
	"return":   RETURN,
	"end":      END,
	"while":    WHILE,
	"for":      FOR,
	"to":       TO,
	"in":       IN,
	"break":    BREAK,
	"continue": CONTINUE,
}

func LookupIdent(ident string) TokenType {
	if _, ok := keywords[ident]; ok {
		return keywords[ident]
	}
	return IDENT
}
